#include "client.h"

/*传送*pstart，长度为len，成功返回1，失败返回0*/
int sendn(int sockFd, void* pstart, int len) {
    int total = 0;
    int ret = 0;
    char* p = (char*)pstart;

    while (total < len) {
        ret = send(sockFd, p + total, len - total, MSG_NOSIGNAL);
        total += ret;
    }
    return 1;
}

/*接收*pstart，长度为len，成功返回1，失败返回0*/
int recvn(int sockFd, void* pstart, int len) {
    int total = 0;
    int ret;
    char* p = (char*)pstart;

    while (total < len) {
        ret = recv(sockFd, p + total, len - total, 0);
        total += ret;
    }
    return 1;
}

/*接收文件，传入用于接收的sockFd，fileName作为传入传出参数来获取接收的文件名*/
/*若接收成功返回1，接收失败返回0*/
int recvFile(const int sockFd, fileInfo_t* pFileBuf) {
    char name[1024] = {0};
    int dataLength;

    //接收文件名长度
    int ret = recvn(sockFd, &dataLength, sizeof(int));
    //接收文件名
    recvn(sockFd, name, dataLength);

    int fd = open(name, O_RDWR | O_CREAT | O_TRUNC, 0666);
    ERROR_CHECK(fd, -1, "open");
    if(fd == -1){
        return 0;
    }

    int fileSize;
    //接收文件大小的大小
    recvn(sockFd, &dataLength, sizeof(int));
    //接收文件大小
    recvn(sockFd, &fileSize, dataLength);
    printf("fileSize = %d\n", fileSize);
    int doneSize = 0;
    int lastSize = 0;
    int slice = fileSize / 10000;

    //固定文件大小
    ftruncate(fd, fileSize);
    //使用
    char* p = (char*)mmap(NULL, fileSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    ERROR_CHECK(p, MAP_FAILED, "mmap");
    if(p == MAP_FAILED){
        return 0;
    }
    
    int total = 0;

    //计时
    time_t timeBeg, timeEnd;
    timeBeg = time(NULL);

    while (total < fileSize) {
        //接收分片长度
        recvn(sockFd, &dataLength, sizeof(int));
        if (dataLength != 1000) {
            printf("dataLength = %d\n", dataLength);
            printf("100.00%%\n");
            break;
        }
        doneSize += dataLength;
        if (doneSize - lastSize > slice) {
            printf("%5.2lf%%\r", 100.0 * doneSize / fileSize);
            fflush(stdout);
            lastSize = doneSize;
        }
        //接收文件分片
        recvn(sockFd, p + total, dataLength);
        total += dataLength;
    }

    //计时结束
    timeEnd = time(NULL);
    printf("totalTime = %lds\n", timeEnd - timeBeg);

    //拷贝文件名和大小
    strcpy(pFileBuf->fileName, name);
    pFileBuf->fileSize = fileSize;

    close(fd);
    munmap(p, fileSize);
    return 1;
}